Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Node / ReticulumProjects / MeshChatX.git / files / tests / backend / test_property_based.py

Displaying Raw • Download


tests/backend/test_property_based.py 1788aea0c2d17db5ae2363191d877c44d7582440 (1788aea0) Text, 11.65 KB

Tff7b72import T7ee787html
Tff7b72import T7ee787json
Tff7b72import T7ee787math
Tff7b72import T7ee787os
Tff7b72import T7ee787shutil

Tff7b72import T7ee787pytest
Tff7b72from T7ee787hypothesis Tff7b72import Te6edf3HealthCheckTb4b4b4, Te6edf3givenTb4b4b4, Te6edf3settings
Tff7b72from T7ee787hypothesis Tff7b72import Te6edf3strategies Tff7b72as Te6edf3st

Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787colour_utils Tff7b72import Te6edf3ColourUtils
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787identity_manager Tff7b72import Te6edf3IdentityManager
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787interface_config_parser Tff7b72import Te6edf3InterfaceConfigParser
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787lxmf_utils Tff7b72import Te6edf3convert_db_lxmf_message_to_dict
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787markdown_renderer Tff7b72import Te6edf3MarkdownRenderer
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787meshchat_utils Tff7b72import Tb4b4b4(
Te6edf3parse_bool_query_paramTb4b4b4,
Te6edf3parse_lxmf_display_nameTb4b4b4,
Te6edf3parse_lxmf_propagation_node_app_dataTb4b4b4,
Te6edf3parse_lxmf_stamp_costTb4b4b4,
Te6edf3parse_nomadnetwork_node_display_nameTb4b4b4,
Tb4b4b4)
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787nomadnet_utils Tff7b72import Tb4b4b4(
Te6edf3convert_nomadnet_field_data_to_mapTb4b4b4,
Te6edf3convert_nomadnet_string_data_to_mapTb4b4b4,
Tb4b4b4)
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787telemetry_utils Tff7b72import Te6edf3Telemeter

T8b949e# Strategies for telemetry data
Te6edf3st_latitude Tff7b72= Te6edf3stTff7b72.Td2a8fffloatsTb4b4b4(
Te6edf3min_valueTff7b72=Tff7b72-T79c0ff90Tb4b4b4,
Te6edf3max_valueTff7b72=T79c0ff90Tb4b4b4,
Te6edf3allow_nanTff7b72=Tff7b72FalseTb4b4b4,
Te6edf3allow_infinityTff7b72=Tff7b72FalseTb4b4b4,
Tb4b4b4)
Te6edf3st_longitude Tff7b72= Te6edf3stTff7b72.Td2a8fffloatsTb4b4b4(
Te6edf3min_valueTff7b72=Tff7b72-T79c0ff180Tb4b4b4,
Te6edf3max_valueTff7b72=T79c0ff180Tb4b4b4,
Te6edf3allow_nanTff7b72=Tff7b72FalseTb4b4b4,
Te6edf3allow_infinityTff7b72=Tff7b72FalseTb4b4b4,
Tb4b4b4)
Te6edf3st_altitude Tff7b72= Te6edf3stTff7b72.Td2a8fffloatsTb4b4b4(
Te6edf3min_valueTff7b72=Tff7b72-T79c0ff10000Tb4b4b4,
Te6edf3max_valueTff7b72=T79c0ff100000Tb4b4b4,
Te6edf3allow_nanTff7b72=Tff7b72FalseTb4b4b4,
Te6edf3allow_infinityTff7b72=Tff7b72FalseTb4b4b4,
Tb4b4b4)
Te6edf3st_speed Tff7b72= Te6edf3stTff7b72.Td2a8fffloatsTb4b4b4(Te6edf3min_valueTff7b72=T79c0ff0Tb4b4b4, Te6edf3max_valueTff7b72=T79c0ff1000Tb4b4b4, Te6edf3allow_nanTff7b72=Tff7b72FalseTb4b4b4, Te6edf3allow_infinityTff7b72=Tff7b72FalseTb4b4b4)
Te6edf3st_bearing Tff7b72= Te6edf3stTff7b72.Td2a8fffloatsTb4b4b4(
Te6edf3min_valueTff7b72=Tff7b72-T79c0ff360Tb4b4b4,
Te6edf3max_valueTff7b72=T79c0ff360Tb4b4b4,
Te6edf3allow_nanTff7b72=Tff7b72FalseTb4b4b4,
Te6edf3allow_infinityTff7b72=Tff7b72FalseTb4b4b4,
Tb4b4b4)
Te6edf3st_accuracy Tff7b72= Te6edf3stTff7b72.Td2a8fffloatsTb4b4b4(
Te6edf3min_valueTff7b72=T79c0ff0Tb4b4b4,
Te6edf3max_valueTff7b72=T79c0ff655.35Tb4b4b4,
Te6edf3allow_nanTff7b72=Tff7b72FalseTb4b4b4,
Te6edf3allow_infinityTff7b72=Tff7b72FalseTb4b4b4,
Tb4b4b4)
Te6edf3st_timestamp Tff7b72= Te6edf3stTff7b72.Td2a8ffintegersTb4b4b4(Te6edf3min_valueTff7b72=T79c0ff0Tb4b4b4, Te6edf3max_valueTff7b72=T79c0ff2Tff7b72*Tff7b72*T79c0ff32 Tff7b72- T79c0ff1Tb4b4b4)


Tf0883e@givenTb4b4b4(
Te6edf3latTff7b72=Te6edf3st_latitudeTb4b4b4,
Te6edf3lonTff7b72=Te6edf3st_longitudeTb4b4b4,
Te6edf3altTff7b72=Te6edf3st_altitudeTb4b4b4,
Te6edf3speedTff7b72=Te6edf3st_speedTb4b4b4,
Te6edf3bearTff7b72=Te6edf3st_bearingTb4b4b4,
Te6edf3accTff7b72=Te6edf3st_accuracyTb4b4b4,
Te6edf3tsTff7b72=Te6edf3st_timestampTb4b4b4,
Tb4b4b4)
Tff7b72def Td2a8fftest_telemeter_location_roundtripTb4b4b4(Te6edf3latTb4b4b4, Te6edf3lonTb4b4b4, Te6edf3altTb4b4b4, Te6edf3speedTb4b4b4, Te6edf3bearTb4b4b4, Te6edf3accTb4b4b4, Te6edf3tsTb4b4b4)Tb4b4b4:
Te6edf3packed Tff7b72= Te6edf3TelemeterTff7b72.Td2a8ffpack_locationTb4b4b4(Te6edf3latTb4b4b4, Te6edf3lonTb4b4b4, Te6edf3altTb4b4b4, Te6edf3speedTb4b4b4, Te6edf3bearTb4b4b4, Te6edf3accTb4b4b4, Te6edf3tsTb4b4b4)
Tff7b72assert Te6edf3packed Tff7b72is Tff7b72not Tff7b72None
Te6edf3unpacked Tff7b72= Te6edf3TelemeterTff7b72.Td2a8ffunpack_locationTb4b4b4(Te6edf3packedTb4b4b4)
Tff7b72assert Te6edf3unpacked Tff7b72is Tff7b72not Tff7b72None

T8b949e# Check with tolerance due to rounding/fixed point conversion in packing
Tff7b72assert Te6edf3mathTff7b72.Td2a8ffiscloseTb4b4b4(Te6edf3unpackedTb4b4b4[Ta5d6ff"Ta5d6fflatitudeTa5d6ff"Tb4b4b4]Tb4b4b4, Te6edf3latTb4b4b4, Te6edf3abs_tolTff7b72=T79c0ff1e-6Tb4b4b4)
Tff7b72assert Te6edf3mathTff7b72.Td2a8ffiscloseTb4b4b4(Te6edf3unpackedTb4b4b4[Ta5d6ff"Ta5d6fflongitudeTa5d6ff"Tb4b4b4]Tb4b4b4, Te6edf3lonTb4b4b4, Te6edf3abs_tolTff7b72=T79c0ff1e-6Tb4b4b4)
Tff7b72assert Te6edf3mathTff7b72.Td2a8ffiscloseTb4b4b4(Te6edf3unpackedTb4b4b4[Ta5d6ff"Ta5d6ffaltitudeTa5d6ff"Tb4b4b4]Tb4b4b4, Te6edf3altTb4b4b4, Te6edf3abs_tolTff7b72=T79c0ff1e-2Tb4b4b4)
Tff7b72assert Te6edf3mathTff7b72.Td2a8ffiscloseTb4b4b4(Te6edf3unpackedTb4b4b4[Ta5d6ff"Ta5d6ffspeedTa5d6ff"Tb4b4b4]Tb4b4b4, Te6edf3speedTb4b4b4, Te6edf3abs_tolTff7b72=T79c0ff1e-2Tb4b4b4)
T8b949e# Bearing can be negative in input but unpacked should match
Tff7b72assert Te6edf3mathTff7b72.Td2a8ffiscloseTb4b4b4(Te6edf3unpackedTb4b4b4[Ta5d6ff"Ta5d6ffbearingTa5d6ff"Tb4b4b4]Tb4b4b4, Te6edf3bearTb4b4b4, Te6edf3abs_tolTff7b72=T79c0ff1e-2Tb4b4b4)
Tff7b72assert Te6edf3mathTff7b72.Td2a8ffiscloseTb4b4b4(Te6edf3unpackedTb4b4b4[Ta5d6ff"Ta5d6ffaccuracyTa5d6ff"Tb4b4b4]Tb4b4b4, Te6edf3accTb4b4b4, Te6edf3abs_tolTff7b72=T79c0ff1e-2Tb4b4b4)
Tff7b72assert Te6edf3unpackedTb4b4b4[Ta5d6ff"Ta5d6fflast_updateTa5d6ff"Tb4b4b4] Tff7b72== Te6edf3ts


Tf0883e@givenTb4b4b4(
Te6edf3time_utcTff7b72=Te6edf3st_timestampTb4b4b4,
Te6edf3latTff7b72=Te6edf3st_latitudeTb4b4b4,
Te6edf3lonTff7b72=Te6edf3st_longitudeTb4b4b4,
Te6edf3chargeTff7b72=Te6edf3stTff7b72.Td2a8ffintegersTb4b4b4(Te6edf3min_valueTff7b72=T79c0ff0Tb4b4b4, Te6edf3max_valueTff7b72=T79c0ff100Tb4b4b4)Tb4b4b4,
Te6edf3chargingTff7b72=Te6edf3stTff7b72.Td2a8ffbooleansTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3rssiTff7b72=Te6edf3stTff7b72.Td2a8ffintegersTb4b4b4(Te6edf3min_valueTff7b72=Tff7b72-T79c0ff150Tb4b4b4, Te6edf3max_valueTff7b72=T79c0ff0Tb4b4b4)Tb4b4b4,
Te6edf3snrTff7b72=Te6edf3stTff7b72.Td2a8ffintegersTb4b4b4(Te6edf3min_valueTff7b72=Tff7b72-T79c0ff20Tb4b4b4, Te6edf3max_valueTff7b72=T79c0ff20Tb4b4b4)Tb4b4b4,
Te6edf3qTff7b72=Te6edf3stTff7b72.Td2a8ffintegersTb4b4b4(Te6edf3min_valueTff7b72=T79c0ff0Tb4b4b4, Te6edf3max_valueTff7b72=T79c0ff100Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72def Td2a8fftest_telemeter_full_pack_roundtripTb4b4b4(
Te6edf3time_utcTb4b4b4,
Te6edf3latTb4b4b4,
Te6edf3lonTb4b4b4,
Te6edf3chargeTb4b4b4,
Te6edf3chargingTb4b4b4,
Te6edf3rssiTb4b4b4,
Te6edf3snrTb4b4b4,
Te6edf3qTb4b4b4,
Tb4b4b4)Tb4b4b4:
Te6edf3location Tff7b72= Tb4b4b4{Ta5d6ff"Ta5d6fflatitudeTa5d6ff"Tb4b4b4: Te6edf3latTb4b4b4, Ta5d6ff"Ta5d6fflongitudeTa5d6ff"Tb4b4b4: Te6edf3lonTb4b4b4}
Te6edf3battery Tff7b72= Tb4b4b4{Ta5d6ff"Ta5d6ffcharge_percentTa5d6ff"Tb4b4b4: Te6edf3chargeTb4b4b4, Ta5d6ff"Ta5d6ffchargingTa5d6ff"Tb4b4b4: Te6edf3chargingTb4b4b4}
Te6edf3physical_link Tff7b72= Tb4b4b4{Ta5d6ff"Ta5d6ffrssiTa5d6ff"Tb4b4b4: Te6edf3rssiTb4b4b4, Ta5d6ff"Ta5d6ffsnrTa5d6ff"Tb4b4b4: Te6edf3snrTb4b4b4, Ta5d6ff"Ta5d6ffqTa5d6ff"Tb4b4b4: Te6edf3qTb4b4b4}

Te6edf3packed Tff7b72= Te6edf3TelemeterTff7b72.Td2a8ffpackTb4b4b4(
Te6edf3time_utcTff7b72=Te6edf3time_utcTb4b4b4,
Te6edf3locationTff7b72=Te6edf3locationTb4b4b4,
Te6edf3batteryTff7b72=Te6edf3batteryTb4b4b4,
Te6edf3physical_linkTff7b72=Te6edf3physical_linkTb4b4b4,
Tb4b4b4)

Te6edf3unpacked Tff7b72= Te6edf3TelemeterTff7b72.Td2a8fffrom_packedTb4b4b4(Te6edf3packedTb4b4b4)
Tff7b72assert Te6edf3unpacked Tff7b72is Tff7b72not Tff7b72None
Tff7b72assert Te6edf3unpackedTb4b4b4[Ta5d6ff"Ta5d6fftimeTa5d6ff"Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffutcTa5d6ff"Tb4b4b4] Tff7b72== Te6edf3time_utc
Tff7b72assert Te6edf3mathTff7b72.Td2a8ffiscloseTb4b4b4(Te6edf3unpackedTb4b4b4[Ta5d6ff"Ta5d6fflocationTa5d6ff"Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6fflatitudeTa5d6ff"Tb4b4b4]Tb4b4b4, Te6edf3latTb4b4b4, Te6edf3abs_tolTff7b72=T79c0ff1e-6Tb4b4b4)
Tff7b72assert Te6edf3mathTff7b72.Td2a8ffiscloseTb4b4b4(Te6edf3unpackedTb4b4b4[Ta5d6ff"Ta5d6fflocationTa5d6ff"Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6fflongitudeTa5d6ff"Tb4b4b4]Tb4b4b4, Te6edf3lonTb4b4b4, Te6edf3abs_tolTff7b72=T79c0ff1e-6Tb4b4b4)
Tff7b72assert Te6edf3unpackedTb4b4b4[Ta5d6ff"Ta5d6ffbatteryTa5d6ff"Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffcharge_percentTa5d6ff"Tb4b4b4] Tff7b72== Te6edf3charge
Tff7b72assert Te6edf3unpackedTb4b4b4[Ta5d6ff"Ta5d6ffbatteryTa5d6ff"Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffchargingTa5d6ff"Tb4b4b4] Tff7b72== Te6edf3charging
Tff7b72assert Te6edf3unpackedTb4b4b4[Ta5d6ff"Ta5d6ffphysical_linkTa5d6ff"Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffrssiTa5d6ff"Tb4b4b4] Tff7b72== Te6edf3rssi
Tff7b72assert Te6edf3unpackedTb4b4b4[Ta5d6ff"Ta5d6ffphysical_linkTa5d6ff"Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffsnrTa5d6ff"Tb4b4b4] Tff7b72== Te6edf3snr
Tff7b72assert Te6edf3unpackedTb4b4b4[Ta5d6ff"Ta5d6ffphysical_linkTa5d6ff"Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffqTa5d6ff"Tb4b4b4] Tff7b72== Te6edf3q


Tf0883e@givenTb4b4b4(Te6edf3hex_valTff7b72=Te6edf3stTff7b72.Td2a8fffrom_regexTb4b4b4(Ta5d6ffrTa5d6ff"Ta5d6ff^#?[0-9a-fA-F]Tffd700{6}Ta5d6ff$Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72def Td2a8fftest_colour_utils_hex_to_byte_arrayTb4b4b4(Te6edf3hex_valTb4b4b4)Tb4b4b4:
Te6edf3result Tff7b72= Te6edf3ColourUtilsTff7b72.Td2a8ffhex_colour_to_byte_arrayTb4b4b4(Te6edf3hex_valTb4b4b4)
Tff7b72assert Tffa657lenTb4b4b4(Te6edf3resultTb4b4b4) Tff7b72== T79c0ff3

T8b949e# Verify manual conversion matches
Te6edf3clean_hex Tff7b72= Te6edf3hex_valTff7b72.Td2a8fflstripTb4b4b4(Ta5d6ff"Ta5d6ff#Ta5d6ff"Tb4b4b4)
Te6edf3expected Tff7b72= Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Te6edf3clean_hexTb4b4b4)
Tff7b72assert Te6edf3result Tff7b72== Te6edf3expected


Tf0883e@givenTb4b4b4(
Te6edf3valTff7b72=Te6edf3stTff7b72.Td2a8ffone_ofTb4b4b4(
Te6edf3stTff7b72.Td2a8ffsampled_fromTb4b4b4(
Tb4b4b4[Ta5d6ff"Ta5d6ff1Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6fftrueTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffyesTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffonTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff0Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6fffalseTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffnoTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffoffTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffrandomTa5d6ff"Tb4b4b4]Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Te6edf3stTff7b72.Td2a8ffnoneTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72def Td2a8fftest_parse_bool_query_paramTb4b4b4(Te6edf3valTb4b4b4)Tb4b4b4:
Te6edf3result Tff7b72= Te6edf3parse_bool_query_paramTb4b4b4(Te6edf3valTb4b4b4)
Tff7b72if Te6edf3val Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72assert Te6edf3result Tff7b72is Tff7b72False
Tff7b72elif Te6edf3valTff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4) Tff7b72in Tb4b4b4{Ta5d6ff"Ta5d6ff1Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6fftrueTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffyesTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffonTa5d6ff"Tb4b4b4}Tb4b4b4:
Tff7b72assert Te6edf3result Tff7b72is Tff7b72True
Tff7b72elseTb4b4b4:
Tff7b72assert Te6edf3result Tff7b72is Tff7b72False


Tf0883e@givenTb4b4b4(Te6edf3dataTff7b72=Te6edf3stTff7b72.Td2a8ffbinaryTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72def Td2a8fftest_parse_lxmf_display_name_robustnessTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4:
T8b949e# This should never crash
Tff7b72tryTb4b4b4:
Te6edf3parse_lxmf_display_nameTb4b4b4(Te6edf3dataTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3pytestTff7b72.Td2a8fffailTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffparse_lxmf_display_name crashed: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4)


Tf0883e@givenTb4b4b4(Te6edf3dataTff7b72=Te6edf3stTff7b72.Td2a8ffbinaryTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72def Td2a8fftest_parse_lxmf_propagation_node_app_data_robustnessTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4:
T8b949e# This should never crash
Tff7b72tryTb4b4b4:
Te6edf3parse_lxmf_propagation_node_app_dataTb4b4b4(Te6edf3dataTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3pytestTff7b72.Td2a8fffailTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffparse_lxmf_propagation_node_app_data crashed: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4)


Tf0883e@givenTb4b4b4(Te6edf3dataTff7b72=Te6edf3stTff7b72.Td2a8ffbinaryTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72def Td2a8fftest_parse_lxmf_stamp_cost_robustnessTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4:
T8b949e# This should never crash
Tff7b72tryTb4b4b4:
Te6edf3parse_lxmf_stamp_costTb4b4b4(Te6edf3dataTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3pytestTff7b72.Td2a8fffailTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffparse_lxmf_stamp_cost crashed: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4)


Tf0883e@givenTb4b4b4(Te6edf3nameTff7b72=Te6edf3stTff7b72.Td2a8fftextTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72def Td2a8fftest_parse_nomadnetwork_node_display_name_robustnessTb4b4b4(Te6edf3nameTb4b4b4)Tb4b4b4:
T8b949e# This should never crash
Tff7b72tryTb4b4b4:
Te6edf3parse_nomadnetwork_node_display_nameTb4b4b4(Te6edf3nameTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3pytestTff7b72.Td2a8fffailTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffparse_nomadnetwork_node_display_name crashed: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4)


Tf0883e@givenTb4b4b4(Te6edf3packedTff7b72=Te6edf3stTff7b72.Td2a8ffbinaryTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72def Td2a8fftest_telemeter_from_packed_robustnessTb4b4b4(Te6edf3packedTb4b4b4)Tb4b4b4:
T8b949e# This should never crash
Tff7b72tryTb4b4b4:
Te6edf3TelemeterTff7b72.Td2a8fffrom_packedTb4b4b4(Te6edf3packedTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3pytestTff7b72.Td2a8fffailTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffTelemeter.from_packed crashed: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4)


Tf0883e@givenTb4b4b4(Te6edf3textTff7b72=Te6edf3stTff7b72.Td2a8fftextTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72def Td2a8fftest_markdown_renderer_no_crashTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Te6edf3textTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3pytestTff7b72.Td2a8fffailTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffMarkdownRenderer.render crashed: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4)


Tf0883e@givenTb4b4b4(Te6edf3textTff7b72=Te6edf3stTff7b72.Td2a8fftextTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72def Td2a8fftest_interface_config_parser_no_crashTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3InterfaceConfigParserTff7b72.Td2a8ffparseTb4b4b4(Te6edf3textTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3pytestTff7b72.Td2a8fffailTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffInterfaceConfigParser.parse crashed: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4)


T8b949e# Strategy for a database message row
Te6edf3st_db_message Tff7b72= Te6edf3stTff7b72.Td2a8ffdictionariesTb4b4b4(
Te6edf3keysTff7b72=Te6edf3stTff7b72.Td2a8ffsampled_fromTb4b4b4(
Tb4b4b4[
Ta5d6ff"Ta5d6ffidTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffhashTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffsource_hashTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffdestination_hashTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffis_incomingTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffstateTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffprogressTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffmethodTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffdelivery_attemptsTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffnext_delivery_attempt_atTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6fftitleTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffcontentTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6fffieldsTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6fftimestampTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffrssiTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffsnrTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffqualityTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffis_spamTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffcreated_atTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffupdated_atTa5d6ff"Tb4b4b4,
Tb4b4b4]Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Te6edf3valuesTff7b72=Te6edf3stTff7b72.Td2a8ffone_ofTb4b4b4(
Te6edf3stTff7b72.Td2a8ffnoneTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3stTff7b72.Td2a8ffintegersTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3stTff7b72.Td2a8fffloatsTb4b4b4(Te6edf3allow_nanTff7b72=Tff7b72FalseTb4b4b4, Te6edf3allow_infinityTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4,
Te6edf3stTff7b72.Td2a8fftextTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3stTff7b72.Td2a8ffbooleansTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3stTff7b72.Td2a8ffbinaryTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffmapTb4b4b4(Tff7b72lambda Te6edf3bTb4b4b4: Te6edf3bTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tff7b72.Td2a8fffilterTb4b4b4(Tff7b72lambda Te6edf3dTb4b4b4: Ta5d6ff"Ta5d6ffcreated_atTa5d6ff" Tff7b72in Te6edf3d Tff7b72and Ta5d6ff"Ta5d6ffupdated_atTa5d6ff" Tff7b72in Te6edf3dTb4b4b4)


Tf0883e@settingsTb4b4b4(Te6edf3suppress_health_checkTff7b72=Tb4b4b4[Te6edf3HealthCheckTff7b72.Td2a8fftoo_slowTb4b4b4]Tb4b4b4)
Tf0883e@givenTb4b4b4(Te6edf3db_messageTff7b72=Te6edf3st_db_messageTb4b4b4)
Tff7b72def Td2a8fftest_convert_db_lxmf_message_to_dict_robustnessTb4b4b4(Te6edf3db_messageTb4b4b4)Tb4b4b4:
T8b949e# Fill in missing required keys for the function
Te6edf3required_keys Tff7b72= Tb4b4b4[
Ta5d6ff"Ta5d6ffidTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffhashTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffsource_hashTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffdestination_hashTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffis_incomingTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffstateTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffprogressTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffmethodTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffdelivery_attemptsTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffnext_delivery_attempt_atTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6fftitleTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffcontentTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6fffieldsTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6fftimestampTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffrssiTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffsnrTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffqualityTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffis_spamTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffcreated_atTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffupdated_atTa5d6ff"Tb4b4b4,
Tb4b4b4]
Tff7b72for Te6edf3key Tff7b72in Te6edf3required_keysTb4b4b4:
Tff7b72if Te6edf3key Tff7b72not Tff7b72in Te6edf3db_messageTb4b4b4:
Te6edf3db_messageTb4b4b4[Te6edf3keyTb4b4b4] Tff7b72= Tff7b72None

T8b949e# Ensure fields is a valid JSON string if it's not None
Tff7b72if Te6edf3db_messageTb4b4b4[Ta5d6ff"Ta5d6fffieldsTa5d6ff"Tb4b4b4] Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3jsonTff7b72.Td2a8ffloadsTb4b4b4(Te6edf3db_messageTb4b4b4[Ta5d6ff"Ta5d6fffieldsTa5d6ff"Tb4b4b4]Tb4b4b4)
Tff7b72except Tb4b4b4(Tf85149ValueErrorTb4b4b4, Tf85149TypeErrorTb4b4b4, Te6edf3jsonTff7b72.Td2a8ffJSONDecodeErrorTb4b4b4)Tb4b4b4:
Te6edf3db_messageTb4b4b4[Ta5d6ff"Ta5d6fffieldsTa5d6ff"Tb4b4b4] Tff7b72= Ta5d6ff"Tffd700{}Ta5d6ff"

Tff7b72tryTb4b4b4:
Te6edf3convert_db_lxmf_message_to_dictTb4b4b4(Te6edf3db_messageTb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
T8b949e# We expect some errors if data is really weird, but it shouldn't crash the whole thing
Tff7b72pass


Tf0883e@givenTb4b4b4(Te6edf3dataTff7b72=Te6edf3stTff7b72.Td2a8ffdictionariesTb4b4b4(Te6edf3keysTff7b72=Te6edf3stTff7b72.Td2a8fftextTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3valuesTff7b72=Te6edf3stTff7b72.Td2a8fftextTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)
Tff7b72def Td2a8fftest_convert_nomadnet_field_data_to_mapTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4:
Te6edf3result Tff7b72= Te6edf3convert_nomadnet_field_data_to_mapTb4b4b4(Te6edf3dataTb4b4b4)
Tff7b72assert Tffa657lenTb4b4b4(Te6edf3resultTb4b4b4) Tff7b72== Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4)
Tff7b72for Te6edf3kTb4b4b4, Te6edf3v Tff7b72in Te6edf3dataTff7b72.Td2a8ffitemsTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72assert Te6edf3resultTb4b4b4[Ta5d6fffTa5d6ff"Ta5d6fffield_Tffd700{Te6edf3kTffd700}Ta5d6ff"Tb4b4b4] Tff7b72== Te6edf3v


Tf0883e@givenTb4b4b4(
Te6edf3dataTff7b72=Te6edf3stTff7b72.Td2a8ffdictionariesTb4b4b4(
Te6edf3keysTff7b72=Te6edf3stTff7b72.Td2a8fftextTb4b4b4(Tb4b4b4)Tff7b72.Td2a8fffilterTb4b4b4(Tff7b72lambda Te6edf3xTb4b4b4: Ta5d6ff"Ta5d6ff=Ta5d6ff" Tff7b72not Tff7b72in Te6edf3x Tff7b72and Ta5d6ff"Ta5d6ff|Ta5d6ff" Tff7b72not Tff7b72in Te6edf3x Tff7b72and Te6edf3xTb4b4b4)Tb4b4b4,
Te6edf3valuesTff7b72=Te6edf3stTff7b72.Td2a8fftextTb4b4b4(Tb4b4b4)Tff7b72.Td2a8fffilterTb4b4b4(Tff7b72lambda Te6edf3xTb4b4b4: Ta5d6ff"Ta5d6ff|Ta5d6ff" Tff7b72not Tff7b72in Te6edf3xTb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72def Td2a8fftest_convert_nomadnet_string_data_to_map_roundtripTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4:
T8b949e# Construct string like key1=val1|key2=val2
Te6edf3input_str Tff7b72= Ta5d6ff"Ta5d6ff|Ta5d6ff"Tff7b72.Td2a8ffjoinTb4b4b4(Tb4b4b4[Ta5d6fffTa5d6ff"Tffd700{Te6edf3kTffd700}Ta5d6ff=Tffd700{Te6edf3vTffd700}Ta5d6ff" Tff7b72for Te6edf3kTb4b4b4, Te6edf3v Tff7b72in Te6edf3dataTff7b72.Td2a8ffitemsTb4b4b4(Tb4b4b4)Tb4b4b4]Tb4b4b4)
Te6edf3result Tff7b72= Te6edf3convert_nomadnet_string_data_to_mapTb4b4b4(Te6edf3input_strTb4b4b4)
Tff7b72assert Tffa657lenTb4b4b4(Te6edf3resultTb4b4b4) Tff7b72== Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4)
Tff7b72for Te6edf3kTb4b4b4, Te6edf3v Tff7b72in Te6edf3dataTff7b72.Td2a8ffitemsTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72assert Te6edf3resultTb4b4b4[Ta5d6fffTa5d6ff"Ta5d6ffvar_Tffd700{Te6edf3kTffd700}Ta5d6ff"Tb4b4b4] Tff7b72== Te6edf3v


Tf0883e@givenTb4b4b4(Te6edf3textTff7b72=Te6edf3stTff7b72.Td2a8fftextTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72def Td2a8fftest_markdown_renderer_xss_protectionTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4:
T8b949e# Basic check: if we use <script>, it should be escaped
Te6edf3input_text Tff7b72= Ta5d6fffTa5d6ff"Ta5d6ff<script>alert(1)</script>Tffd700{Te6edf3textTffd700}Ta5d6ff"
Te6edf3result Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Te6edf3input_textTb4b4b4)
Tff7b72assert Ta5d6ff"Ta5d6ff<script>Ta5d6ff" Tff7b72not Tff7b72in Te6edf3result
Tff7b72assert Ta5d6ff"Ta5d6ff&lt;script&gt;Ta5d6ff" Tff7b72in Te6edf3result


Tf0883e@givenTb4b4b4(Te6edf3contentTff7b72=Te6edf3stTff7b72.Td2a8fftextTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72def Td2a8fftest_markdown_renderer_headersTb4b4b4(Te6edf3contentTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3content Tff7b72and Ta5d6ff"Tffea00\nTa5d6ff" Tff7b72not Tff7b72in Te6edf3contentTb4b4b4:
Te6edf3input_text Tff7b72= Ta5d6fffTa5d6ff"Ta5d6ff# Tffd700{Te6edf3contentTffd700}Ta5d6ff"
Te6edf3result Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Te6edf3input_textTb4b4b4)
Tff7b72assert Ta5d6ff"Ta5d6ff<h1Ta5d6ff" Tff7b72in Te6edf3result
Tff7b72assert Te6edf3htmlTff7b72.Td2a8ffescapeTb4b4b4(Te6edf3contentTb4b4b4) Tff7b72in Te6edf3result


Tf0883e@givenTb4b4b4(Te6edf3dataTff7b72=Te6edf3stTff7b72.Td2a8ffbinaryTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72def Td2a8fftest_identity_restore_robustnessTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4:
Te6edf3manager Tff7b72= Te6edf3IdentityManagerTb4b4b4(Ta5d6ff"Ta5d6ff/tmp/test_identitiesTa5d6ff"Tb4b4b4)
Tff7b72tryTb4b4b4:
T8b949e# Should either return a dict or raise ValueError, but not crash
Te6edf3managerTff7b72.Td2a8ffrestore_identity_from_bytesTb4b4b4(Te6edf3dataTb4b4b4)
Tff7b72except Tf85149ValueErrorTb4b4b4:
Tff7b72pass
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3pytestTff7b72.Td2a8fffailTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffrestore_identity_from_bytes crashed with: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4)
Tff7b72finallyTb4b4b4:
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffexistsTb4b4b4(Ta5d6ff"Ta5d6ff/tmp/test_identitiesTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3shutilTff7b72.Td2a8ffrmtreeTb4b4b4(Ta5d6ff"Ta5d6ff/tmp/test_identitiesTa5d6ff"Tb4b4b4)


Tf0883e@givenTb4b4b4(Te6edf3dataTff7b72=Te6edf3stTff7b72.Td2a8fftextTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72def Td2a8fftest_identity_restore_base32_robustnessTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4:
Te6edf3manager Tff7b72= Te6edf3IdentityManagerTb4b4b4(Ta5d6ff"Ta5d6ff/tmp/test_identities_b32Ta5d6ff"Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3managerTff7b72.Td2a8ffrestore_identity_from_base32Tb4b4b4(Te6edf3dataTb4b4b4)
Tff7b72except Tf85149ValueErrorTb4b4b4:
Tff7b72pass
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3pytestTff7b72.Td2a8fffailTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffrestore_identity_from_base32 crashed with: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4)
Tff7b72finallyTb4b4b4:
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffexistsTb4b4b4(Ta5d6ff"Ta5d6ff/tmp/test_identities_b32Ta5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3shutilTff7b72.Td2a8ffrmtreeTb4b4b4(Ta5d6ff"Ta5d6ff/tmp/test_identities_b32Ta5d6ff"Tb4b4b4)


Tf0883e@givenTb4b4b4(
Te6edf3stTff7b72.Td2a8fflistsTb4b4b4(
Te6edf3stTff7b72.Td2a8fftextTb4b4b4(Te6edf3min_sizeTff7b72=T79c0ff1Tb4b4b4)Tff7b72.Td2a8fffilterTb4b4b4(
Tff7b72lambda Te6edf3xTb4b4b4: Ta5d6ff"Tffea00\nTa5d6ff" Tff7b72not Tff7b72in Te6edf3x Tff7b72and Te6edf3xTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4) Tff7b72and Te6edf3xTff7b72.Td2a8ffisalnumTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72def Td2a8fftest_markdown_renderer_list_renderingTb4b4b4(Te6edf3itemsTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3itemsTb4b4b4:
Tff7b72return
Te6edf3markdown Tff7b72= Ta5d6ff"Tffea00\nTa5d6ff"Tff7b72.Td2a8ffjoinTb4b4b4(Tb4b4b4[Ta5d6fffTa5d6ff"Ta5d6ff* Tffd700{Te6edf3itemTffd700}Ta5d6ff" Tff7b72for Te6edf3item Tff7b72in Te6edf3itemsTb4b4b4]Tb4b4b4)
Te6edf3html_output Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Te6edf3markdownTb4b4b4)
Tff7b72assert Ta5d6ff"Ta5d6ff<ulTa5d6ff" Tff7b72in Te6edf3html_output
Tff7b72for Te6edf3item Tff7b72in Te6edf3itemsTb4b4b4:
Tff7b72assert Te6edf3item Tff7b72in Te6edf3html_output


Tf0883e@givenTb4b4b4(
Te6edf3stTff7b72.Td2a8fftextTb4b4b4(Te6edf3min_sizeTff7b72=T79c0ff1Tb4b4b4)Tff7b72.Td2a8fffilterTb4b4b4(Tff7b72lambda Te6edf3xTb4b4b4: Te6edf3xTff7b72.Td2a8ffisalnumTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4,
Te6edf3stTff7b72.Td2a8fftextTb4b4b4(Te6edf3min_sizeTff7b72=T79c0ff1Tb4b4b4)Tff7b72.Td2a8fffilterTb4b4b4(Tff7b72lambda Te6edf3xTb4b4b4: Te6edf3xTff7b72.Td2a8ffisalnumTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72def Td2a8fftest_markdown_renderer_link_renderingTb4b4b4(Te6edf3labelTb4b4b4, Te6edf3urlTb4b4b4)Tb4b4b4:
Te6edf3markdown Tff7b72= Ta5d6fffTa5d6ff"Ta5d6ff[Tffd700{Te6edf3labelTffd700}Ta5d6ff](Tffd700{Te6edf3urlTffd700}Ta5d6ff)Ta5d6ff"
Te6edf3html_output Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Te6edf3markdownTb4b4b4)
Tff7b72assert Ta5d6ff"Ta5d6ff<a href=Ta5d6ff" Tff7b72in Te6edf3html_output
Tff7b72assert Te6edf3label Tff7b72in Te6edf3html_output


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────